// 引入React Hooks和其他依赖
import { useState, useEffect, useRef } from "react";
import { Input, Button, Card, Modal, Checkbox, Select } from "antd"; // Ant Design 组件
import { bind, unbind, send } from "@kuyoonjo/tauri-plugin-udp"; // UDP 插件方法
import { listen } from "@tauri-apps/api/event"; // 事件监听
import HexForm, { defaultAutoData } from "./AutoRepeat"; // 自定义表单组件与默认自动回复数据
import HexInput from "./HexInput"; // 十六进制输入组件
import dayjs from "dayjs";
import { getInterfaces } from "tauri-plugin-network-api";
import "./App.css";

function getLocalIP() {
  return getInterfaces().then((ifaces) => {
    const ips: string[] = [];
    ifaces.forEach((item) => {
      item.v4_addrs?.forEach?.((ip4) => {
        ips.push(ip4.ip);
      });
    });
    return ips;
  });
}

// 将字节数组转换为十六进制字符串
function bytesToHex(bytes: number[]) {
  return bytes.map((byte) => byte.toString(16).padStart(2, "0")).join(" ");
}

// 将十六进制字符串转换为字节数组
function hexToBytes(hexString: string) {
  const bytes = hexString.replace(/\s+/g, "").match(/.{1,2}/g); // 清理非十六进制字符，并按每两位分组
  return bytes ? bytes.map((byte) => parseInt(byte, 16)) : []; // 转换为整数数组
}

interface IMsg {
  type: "in" | "out";
  time: string;
  value: string;
}

function saveArrayAsTxtFile(array: IMsg[], filename = "output.txt") {
  // 将数组转换为字符串，每个元素占一行
  const content = array
    ?.map((item) => {
      return `${item.time} ${item.type} : ${item.value}`;
    })
    .join("\n");

  // 创建一个 Blob 对象
  const blob = new Blob([content], { type: "text/plain" });

  // 创建一个下载链接
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = filename;

  // 触发点击事件来下载文件
  document.body.appendChild(link);
  link.click();

  // 清理
  document.body.removeChild(link);
  URL.revokeObjectURL(link.href);
}

// 发送十六进制数据
const sendHex = (
  destIP: string,
  destPort: number,
  hexStr: string,
  id: string
) => {
  const bytes = hexToBytes(hexStr); // 将十六进制字符串转换为字节数组
  return send(id, `${destIP}:${destPort}`, bytes).catch((err) => {
    console.error("%c Line:63 🍐", "color:#7f2b82", err);
    alert(`消息发送失败: ${err}`); // 显示发送失败信息
  }); // 发送数据
};

// 获取自动回复配置
const getAutoReport = (msg: string) => {
  return (window as any).list?.find?.((item: any) => item.hex1 === msg); // 查找匹配的消息
};

function customRandomString(
  length = 8,
  charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
) {
  let result = "";
  for (let i = 0; i < length; i++) {
    result += charset.charAt(Math.floor(Math.random() * charset.length));
  }
  return result;
}

// 主应用组件
const App = () => {
  const idRef = useRef(customRandomString());
  const [ipOptions, setIps] = useState<{ label: string; value: string }[]>([
    { label: "127.0.0.1", value: "127.0.0.1" },
  ]);
  const [_, setLocalIP] = useState("127.0.0.1"); // 本地IP地址
  const [type, setType] = useState(0); // 当前状态，0:未启动, 1:已启动
  const [localPort, setLocalPort] = useState(8080); // 本地端口号
  const [destIP, setDestIP] = useState("127.0.0.1"); // 目标IP地址
  const [destPort, setDestPort] = useState(8080); // 目标端口号

  const [msg, setMsg] = useState<IMsg[]>([]); //消息列表
  const [message, setMessages] = useState<string>(""); // 待发送的消息
  const listenRef = useRef<any>(); // 保存监听函数引用
  const [isModalOpen, setIsModalOpen] = useState(false); // 控制模态框显示状态
  const timteIntervalFlag = useRef<{ flag: any; time: number }>({
    flag: null,
    time: 1000,
  }); // 定时

  const addMsg = (type: "in" | "out", hex: string) => {
    setMsg((m) => [
      { type, time: dayjs().format("HH:mm:ss.SSS"), value: hex },
      ...m,
    ]);
  };
  // 组件挂载或卸载时执行
  useEffect(() => {
    (window as any).list = defaultAutoData(); // 初始化自动回复列表

    getLocalIP().then((ips) => {
      setIps(ips?.map((v) => ({ label: v, value: v })));
    });
    // 监听UDP消息
    listen("plugin://udp", (x: any) => {
      const hex = bytesToHex(x.payload.data); // 将接收到的数据转换为十六进制字符串
      const auto = getAutoReport(hex); // 查找自动回复配置
      if (auto) {
        setTimeout(() => {
          addMsg("out", auto.hex2);
          sendHex(destIP, destPort, auto.hex2, idRef.current); // 如果有匹配的自动回复，则发送回复
        }, 100);
      }

      addMsg("in", hex);
    }).then((fn) => {
      listenRef.current = fn; // 保存监听函数引用以便后续移除
    });

    // 组件卸载时清理监听
    return () => {
      listenRef.current?.();
    };
  }, [destIP, destPort]);

  // 启动UDP服务器
  const handleStartServer = async () => {
    try {
      await bind(idRef.current, `0.0.0.0:${localPort}`); // 绑定UDP服务器到指定端口
      setType(1); // 更新状态为已启动
    } catch (error) {
      console.error(error);
      alert(`UDP 服务启动失败: ${error}`); // 显示错误信息
    }
  };

  // 关闭UDP服务器
  const handleCloseServer = async () => {
    unbind(idRef.current); // 解绑UDP服务器
    setType(0); // 更新状态为未启动
  };

  // 发送消息
  const handleSendMessage = async () => {
    if (!message) return; // 如果没有消息则不发送
    try {
      addMsg("out", message);
      sendHex(destIP, destPort, message, idRef.current); // 发送十六进制消息
    } catch (error) {
      console.error(error);
      alert(`消息发送失败: ${error}`); // 显示发送失败信息
    }
  };

  // 返回React元素
  return (
    <div>
      {/* UDP连接信息卡片 */}
      <Card title="UDP连接信息">
        <table>
          <tbody>
            <tr>
              <td>本机IP端口：</td>
              <td>
                <Select
                  disabled={!!type}
                  options={ipOptions}
                  onChange={(v) => {
                    setLocalIP(v);
                  }}
                  style={{ minWidth: "200px" }}
                ></Select>
                ：
                <Input
                  style={{ display: "inline-block", width: 80 }}
                  type="number"
                  disabled={!!type}
                  value={localPort}
                  onChange={(e) => setLocalPort(Number(e.target.value))}
                />
              </td>
            </tr>
            <tr>
              <td>远端IP端口：</td>
              <td>
                <Input
                  style={{ display: "inline-block", width: 150 }}
                  type="ip"
                  value={destIP}
                  onChange={(e) => setDestIP(e.target.value)}
                />
                ：
                <Input
                  style={{ display: "inline-block", width: 80 }}
                  type="number"
                  value={destPort}
                  onChange={(e) => setDestPort(Number(e.target.value))}
                />
              </td>
            </tr>
          </tbody>
        </table>
        {type === 0 ? (
          <Button type="primary" onClick={handleStartServer}>
            打开
          </Button>
        ) : (
          <Button type="primary" onClick={handleCloseServer}>
            关闭
          </Button>
        )}
      </Card>

      {/* 数据卡片 */}
      <Card
        title="数据"
        style={{ marginTop: "10px" }}
        extra={
          <>
            <Button
              onClick={() => {
                setIsModalOpen(true);
              }}
            >
              自动回复
            </Button>

            <Button
              onClick={() => {
                saveArrayAsTxtFile(msg, `${new Date().getTime()}.txt`);
              }}
              style={{ marginLeft: "8px" }}
            >
              保存数据
            </Button>

            <Button
              onClick={() => {
                setMsg([]); // 清空接收消息
              }}
              style={{ marginLeft: "8px" }}
            >
              清空数据
            </Button>
          </>
        }
      >
        <div>
          <div
            style={{
              padding: "20px",
              height: "300px",
              overflowY: "auto",
              border: "#ccc solid 1px",
              borderRadius: "8px",
            }}
          >
            {msg?.map?.((item) => (
              <div key={`${item.time}${item.value}`}>
                <span>{item.time}</span>{" "}
                <span className={item.type}>{item.value}</span>
              </div>
            ))}{" "}
            {/* 显示接收消息 */}
          </div>
          <div style={{ display: "flex", marginTop: "20px" }}>
            <HexInput value={message} onChange={(v: any) => setMessages(v)} />{" "}
            {/* 十六进制输入框 */}
            <Button
              style={{ marginLeft: "8px" }}
              type="primary"
              onClick={handleSendMessage}
            >
              发送
            </Button>{" "}
            {/* 发送按钮 */}
          </div>
          <div
            style={{
              display: "flex",
              justifyContent: "end",
              alignItems: "center",
            }}
          >
            <Checkbox
              onChange={(e) => {
                console.log(e, timteIntervalFlag.current);
                window.clearInterval(timteIntervalFlag.current?.flag);
                if (e.target.checked) {
                  timteIntervalFlag.current.flag = setInterval(() => {
                    handleSendMessage();
                  }, timteIntervalFlag.current.time);
                }
              }}
            >
              定时发送
            </Checkbox>
            <Input
              style={{ width: "150px" }}
              defaultValue={1000}
              type="number"
              suffix={"ms/次"}
              onChange={(v) => {
                timteIntervalFlag.current.time = Number(v.target.value);
              }}
            ></Input>
          </div>
        </div>
      </Card>

      {/* 自动回复设置模态框 */}
      <Modal
        title="自动回复设置"
        open={isModalOpen}
        onOk={() => setIsModalOpen(false)}
        onCancel={() => setIsModalOpen(false)}
        width={"80vw"}
        destroyOnClose
        footer={null}
      >
        <HexForm />
      </Modal>
    </div>
  );
};

export default App;
